home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Thread.java < prev    next >
Text File  |  1998-09-22  |  34KB  |  960 lines

  1. /*
  2.  * @(#)Thread.java    1.71 98/08/06
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.lang;
  16.  
  17. /**
  18.  * A <i>thread</i> is a thread of execution in a program. The Java 
  19.  * Virtual Machine allows an application to have multiple threads of 
  20.  * execution running concurrently. 
  21.  * <p>
  22.  * Every thread has a priority. Threads with higher priority are 
  23.  * executed in preference to threads with lower priority. Each thread 
  24.  * may or may not also be marked as a daemon. When code running in 
  25.  * some thread creates a new <code>Thread</code> object, the new 
  26.  * thread has its priority initially set equal to the priority of the 
  27.  * creating thread, and is a daemon thread if and only if the 
  28.  * creating thread is a daemon. 
  29.  * <p>
  30.  * When a Java Virtual Machine starts up, there is usually a single 
  31.  * non-daemon thread (which typically calls the method named 
  32.  * <code>main</code> of some designated class). The Java Virtual 
  33.  * Machine continues to execute threads until either of the following 
  34.  * occurs: 
  35.  * <ul>
  36.  * <li>The <code>exit</code> method of class <code>Runtime</code> has been 
  37.  *     called and the security manager has permitted the exit operation 
  38.  *     to take place. 
  39.  * <li>All threads that are not daemon threads have died, either by 
  40.  *     returning from the call to the <code>run</code> method or by 
  41.  *     performing the <code>stop</code> method. 
  42.  * </ul>
  43.  * <p>
  44.  * There are two ways to create a new thread of execution. One is to 
  45.  * declare a class to be a subclass of <code>Thread</code>. This 
  46.  * subclass should override the <code>run</code> method of class 
  47.  * <code>Thread</code>. An instance of the subclass can then be 
  48.  * allocated and started. For example, a thread that computes primes 
  49.  * larger than a stated value could be written as follows: 
  50.  * <p><hr><blockquote><pre>
  51.  *     class PrimeThread extends Thread {
  52.  *         long minPrime;
  53.  *         PrimeThread(long minPrime) {
  54.  *             this.minPrime = minPrime;
  55.  *         }
  56.  * 
  57.  *         public void run() {
  58.  *             // compute primes larger than minPrime
  59.  *              . . .
  60.  *         }
  61.  *     }
  62.  * </pre></blockquote><hr>
  63.  * <p>
  64.  * The following code would then create a thread and start it running: 
  65.  * <p><blockquote><pre>
  66.  *     PrimeThread p = new PrimeThread(143);
  67.  *     p.start();
  68.  * </pre></blockquote>
  69.  * <p>
  70.  * The other way to create a thread is to declare a class that 
  71.  * implements the <code>Runnable</code> interface. That class then 
  72.  * implements the <code>run</code> method. An instance of the class can 
  73.  * then be allocated, passed as an argument when creating 
  74.  * <code>Thread</code>, and started. The same example in this other 
  75.  * style looks like the following: 
  76.  * <p><hr><blockquote><pre>
  77.  *     class PrimeRun implements Runnable {
  78.  *         long minPrime;
  79.  *         PrimeRun(long minPrime) {
  80.  *             this.minPrime = minPrime;
  81.  *         }
  82.  * 
  83.  *         public void run() {
  84.  *             // compute primes larger than minPrime
  85.  *              . . .
  86.  *         }
  87.  *     }
  88.  * </pre></blockquote><hr>
  89.  * <p>
  90.  * The following code would then create a thread and start it running: 
  91.  * <p><blockquote><pre>
  92.  *     PrimeRun p = new PrimeRun(143);
  93.  *     new Thread(p).start();
  94.  * </pre></blockquote>
  95.  * <p>
  96.  * Every thread has a name for identification purposes. More than 
  97.  * one thread may have the same name. If a name is not specified when 
  98.  * a thread is created, a new name is generated for it. 
  99.  *
  100.  * @author  unascribed
  101.  * @version 1.71, 08/06/98
  102.  * @see     java.lang.Runnable
  103.  * @see     java.lang.Runtime#exit(int)
  104.  * @see     java.lang.Thread#run()
  105.  * @see     java.lang.Thread#stop()
  106.  * @since   JDK1.0
  107.  */
  108. public
  109. class Thread implements Runnable {
  110.     private char    name[];
  111.     private int         priority;
  112.     private Thread    threadQ;
  113.     private int     PrivateInfo;
  114.     private int        eetop;
  115.  
  116.     /* Whether or not to single_step this thread. */
  117.     private boolean    single_step;
  118.  
  119.     /* Whether or not the thread is a daemon thread. */
  120.     private boolean    daemon = false;
  121.  
  122.     /* Whether or not this thread was asked to exit before it runs.*/
  123.     private boolean    stillborn = false;
  124.  
  125.     /* What will be run. */
  126.     private Runnable target;
  127.  
  128.     /* The system queue of threads is linked through activeThreadQueue. */
  129.     private static Thread activeThreadQ;
  130.  
  131.     /* The group of this thread */
  132.     private ThreadGroup    group;
  133.  
  134.     /* For autonumbering anonymous threads. */
  135.     private static int threadInitNumber;
  136.     private static synchronized int nextThreadNum() {
  137.     return threadInitNumber++;
  138.     }
  139.  
  140.     /* The initial segment of the Java stack (not necessarily initialized) */
  141.     private int    initial_stack_memory;
  142.  
  143.     /**
  144.      * The minimum priority that a thread can have. 
  145.      *
  146.      * @since   JDK1.0
  147.      */
  148.     public final static int MIN_PRIORITY = 1;
  149.  
  150.    /**
  151.      * The default priority that is assigned to a thread. 
  152.      *
  153.      * @since   JDK1.0
  154.      */
  155.     public final static int NORM_PRIORITY = 5;
  156.  
  157.     /**
  158.      * The maximum priority that a thread can have. 
  159.      *
  160.      * @since   JDK1.0
  161.      */
  162.     public final static int MAX_PRIORITY = 10;
  163.  
  164.     /**
  165.      * Returns a reference to the currently executing thread object.
  166.      *
  167.      * @return  the currently executing thread.
  168.      * @since   JDK1.0
  169.      */
  170.     public static native Thread currentThread();
  171.  
  172.     /**
  173.      * Causes the currently executing thread object to temporarily pause 
  174.      * and allow other threads to execute. 
  175.      *
  176.      * @since   JDK1.0
  177.      */
  178.     public static native void yield();
  179.  
  180.     /**    
  181.      * Causes the currently executing thread to sleep (temporarily cease 
  182.      * execution) for the specified number of milliseconds. The thread 
  183.      * does not lose ownership of any monitors.
  184.      *
  185.      * @param      millis   the length of time to sleep in milliseconds.
  186.      * @exception  InterruptedException  if another thread has interrupted
  187.      *               this thread.
  188.      * @see        java.lang.Object#notify()
  189.      * @since      JDK1.0
  190.      */
  191.     public static native void sleep(long millis) throws InterruptedException;
  192.  
  193.     /**
  194.      * Causes the currently executing thread to sleep (cease execution) 
  195.      * for the specified number of milliseconds plus the specified number 
  196.      * of nanoseconds. The thread does not lose ownership of any monitors.
  197.      *
  198.      * @param      millis   the length of time to sleep in milliseconds.
  199.      * @param      nanos    0-999999 additional nanoseconds to sleep.
  200.      * @exception  IllegalArgumentException  if the value of millis is negative
  201.      *               or the value of nanos is not in the range 0-999999.
  202.      * @exception  InterruptedException  if another thread has interrupted
  203.      *               this thread.
  204.      * @see        java.lang.Object#notify()
  205.      * @since      JDK1.0
  206.      */
  207.     public static void sleep(long millis, int nanos) 
  208.     throws InterruptedException {
  209.     if (millis < 0) {
  210.             throw new IllegalArgumentException("timeout value is negative");
  211.     }
  212.  
  213.     if (nanos < 0 || nanos > 999999) {
  214.             throw new IllegalArgumentException(
  215.                 "nanosecond timeout value out of range");
  216.     }
  217.  
  218.     if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
  219.         millis++;
  220.     }
  221.  
  222.     sleep(millis);
  223.     }
  224.  
  225.     /**
  226.      * Initialize a Thread.
  227.      *
  228.      * @param g the Thread group
  229.      * @param target the object whose run() method gets called
  230.      * @param name the name of the new Thread
  231.      */
  232.     private void init(ThreadGroup g, Runnable target, String name){
  233.     Thread parent = currentThread();
  234.     if (g == null) {
  235.         /* Determine if it's an applet or not */
  236.         SecurityManager security = System.getSecurityManager();
  237.         
  238.         /* If there is a security manager, ask the security manager
  239.            what to do. */
  240.         if (security != null) {
  241.         g = security.getThreadGroup();
  242.         }
  243.  
  244.         /* If the security doesn't have a strong opinion of the matter
  245.            use the parent thread group. */
  246.         if (g == null) {
  247.         g = parent.getThreadGroup();
  248.         }
  249.     }
  250.  
  251.     /* checkAccess regardless of whether or not threadgroup is
  252.            explicitly passed in. */
  253.     g.checkAccess();        
  254.  
  255.     this.group = g;
  256.     this.daemon = parent.isDaemon();
  257.     this.priority = parent.getPriority();
  258.     this.name = name.toCharArray();
  259.     this.target = target;
  260.     setPriority(priority);
  261.     g.add(this);
  262.     }
  263.  
  264.    /**
  265.      * Allocates a new <code>Thread</code> object. This constructor has 
  266.      * the same effect as <code>Thread(null, null,</code>
  267.      * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is 
  268.      * a newly generated name. Automatically generated names are of the 
  269.      * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 
  270.      * <p>
  271.      * Threads created this way must have overridden their
  272.      * <code>run()</code> method to actually do anything.  An example
  273.      * illustrating this method being used follows:
  274.      * <p><blockquote><pre>
  275.      *     import java.lang.*; 
  276.      *
  277.      *     class plain01 implements Runnable {
  278.      *         String name; 
  279.      *         plain01() {
  280.      *             name = null;
  281.      *         }
  282.      *         plain01(String s) {
  283.      *             name = s;
  284.      *         }
  285.      *         public void run() {
  286.      *             if (name == null)
  287.      *                 System.out.println("A new thread created");
  288.      *             else
  289.      *                 System.out.println("A new thread with name " + name +
  290.      *                                    " created");
  291.      *         }
  292.      *     }
  293.      *     class threadtest01 {
  294.      *         public static void main(String args[] ) {
  295.      *             int failed = 0 ;
  296.      *
  297.      *             <b>Thread t1 = new Thread();</b>  
  298.      *             if (t1 != null)
  299.      *                 System.out.println("new Thread() succeed");
  300.      *             else {
  301.      *                 System.out.println("new Thread() failed"); 
  302.      *                 failed++; 
  303.      *             }
  304.      *         }
  305.      *     }
  306.      * </pre></blockquote>
  307.      *
  308.      * @see     java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  309.      * @since   JDK1.0
  310.      */
  311.     public Thread() {
  312.     init(null, null, "Thread-" + nextThreadNum());
  313.     }
  314.  
  315.     /**
  316.      * Allocates a new <code>Thread</code> object. This constructor has 
  317.      * the same effect as <code>Thread(null, target,</code>
  318.      * <i>gname</i><code>)</code>, where <i>gname</i> is 
  319.      * a newly generated name. Automatically generated names are of the 
  320.      * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 
  321.      *
  322.      * @param   target   the object whose <code>run</code> method is called.
  323.      * @see     java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  324.      * @since   JDK1.0
  325.      */
  326.     public Thread(Runnable target) {
  327.     init(null, target, "Thread-" + nextThreadNum());
  328.     }
  329.  
  330.     /**
  331.      * Allocates a new <code>Thread</code> object. This constructor has 
  332.      * the same effect as <code>Thread(group, target,</code>
  333.      * <i>gname</i><code>)</code>, where <i>gname</i> is 
  334.      * a newly generated name. Automatically generated names are of the 
  335.      * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer. 
  336.      *
  337.      * @param      group    the thread group.
  338.      * @param      target   the object whose <code>run</code> method is called.
  339.      * @exception  SecurityException  if the current thread cannot create a
  340.      *               thread in the specified thread group.
  341.      * @see        java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  342.      * @since      JDK1.0
  343.      */
  344.     public Thread(ThreadGroup group, Runnable target) {
  345.     init(group, target, "Thread-" + nextThreadNum());
  346.     }
  347.  
  348.     /**
  349.      * Allocates a new <code>Thread</code> object. This constructor has 
  350.      * the same effect as <code>Thread(null, null, name)</code>. 
  351.      *
  352.      * @param   name   the name of the new thread.
  353.      * @see     java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  354.      * @since   JDK1.0
  355.      */
  356.     public Thread(String name) {
  357.     init(null, null, name);
  358.     }
  359.  
  360.     /**
  361.      * Allocates a new <code>Thread</code> object. This constructor has 
  362.      * the same effect as <code>Thread(group, null, name)</code> 
  363.      *
  364.      * @param      group   the thread group.
  365.      * @param      name    the name of the new thread.
  366.      * @exception  SecurityException  if the current thread cannot create a
  367.      *               thread in the specified thread group.
  368.      * @see        java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  369.      * @since   JDK1.0
  370.      */
  371.     public Thread(ThreadGroup group, String name) {
  372.     init(group, null, name);
  373.     }
  374.  
  375.     /**
  376.      * Allocates a new <code>Thread</code> object. This constructor has 
  377.      * the same effect as <code>Thread(null, target, name)</code>. 
  378.      *
  379.      * @param   target   the object whose <code>run</code> method is called.
  380.      * @param   name     the name of the new thread.
  381.      * @see     java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  382.      * @since   JDK1.0
  383.      */
  384.     public Thread(Runnable target, String name) {
  385.     init(null, target, name);
  386.     }
  387.  
  388.     /**
  389.      * Allocates a new <code>Thread</code> object so that it has 
  390.      * <code>target</code> as its run object, has the specified 
  391.      * <code>name</code> as its name, and belongs to the thread group 
  392.      * referred to by <code>group</code>.
  393.      * <p>
  394.      * If <code>group</code> is not <code>null</code>, the 
  395.      * <code>checkAccess</code> method of that thread group is called with 
  396.      * no arguments; this may result in throwing a 
  397.      * <code>SecurityException</code>; if <code>group</code> is 
  398.      * <code>null</code>, the new process belongs to the same group as 
  399.      * the thread that is creating the new thread. 
  400.      * <p>
  401.      * If the <code>target</code> argument is not <code>null</code>, the 
  402.      * <code>run</code> method of the <code>target</code> is called when 
  403.      * this thread is started. If the target argument is 
  404.      * <code>null</code>, this thread's <code>run</code> method is called 
  405.      * when this thread is started. 
  406.      * <p>
  407.      * The priority of the newly created thread is set equal to the 
  408.      * priority of the thread creating it, that is, the currently running 
  409.      * thread. The method <code>setPriority</code> may be used to 
  410.      * change the priority to a new value. 
  411.      * <p>
  412.      * The newly created thread is initially marked as being a daemon 
  413.      * thread if and only if the thread creating it is currently marked 
  414.      * as a daemon thread. The method <code>setDaemon </code> may be used 
  415.      * to change whether or not a thread is a daemon. 
  416.      *
  417.      * @param      group     the thread group.
  418.      * @param      target   the object whose <code>run</code> method is called.
  419.      * @param      name     the name of the new thread.
  420.      * @exception  SecurityException  if the current thread cannot create a
  421.      *               thread in the specified thread group.
  422.      * @see        java.lang.Runnable#run()
  423.      * @see        java.lang.Thread#run()
  424.      * @see        java.lang.Thread#setDaemon(boolean)
  425.      * @see        java.lang.Thread#setPriority(int)
  426.      * @see        java.lang.ThreadGroup#checkAccess()
  427.      * @since      JDK1.0
  428.      */
  429.     public Thread(ThreadGroup group, Runnable target, String name) {
  430.     init(group, target, name);
  431.     }
  432.  
  433.     /**
  434.      * Causes this thread to begin execution; the Java Virtual Machine 
  435.      * calls the <code>run</code> method of this thread. 
  436.      * <p>
  437.      * The result is that two threads are running concurrently: the 
  438.      * current thread (which returns from the call to the 
  439.      * <code>start</code> method) and the other thread (which executes its 
  440.      * <code>run</code> method). 
  441.      *
  442.      * @exception  IllegalThreadStateException  if the thread was already
  443.      *               started.
  444.      * @see        java.lang.Thread#run()
  445.      * @see        java.lang.Thread#stop()
  446.      * @since      JDK1.0
  447.      */
  448.     public synchronized native void start();
  449.  
  450.     /**
  451.      * If this thread was constructed using a separate 
  452.      * <code>Runnable</code> run object, then that 
  453.      * <code>Runnable</code> object's <code>run</code> method is called; 
  454.      * otherwise, this method does nothing and returns. 
  455.      * <p>
  456.      * Subclasses of <code>Thread</code> should override this method. 
  457.      *
  458.      * @see     java.lang.Thread#start()
  459.      * @see     java.lang.Thread#stop()
  460.      * @see     java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable, java.lang.String)
  461.      * @see     java.lang.Runnable#run()
  462.      * @since   JDK1.0
  463.      */
  464.     public void run() {
  465.     if (target != null) {
  466.         target.run();
  467.     }
  468.     }
  469.  
  470.     /**
  471.      * This method is called by the system to give a Thread
  472.      * a chance to clean up before it actually exits.
  473.      */
  474.     private void exit() {
  475.     if (group != null) {
  476.         group.remove(this);
  477.         group = null;
  478.     }
  479.     /* Aggressively null object connected to Thread: see bug 4006245 */
  480.     target = null;
  481.     }
  482.  
  483.     /** 
  484.      * Forces the thread to stop executing. 
  485.      * <p>
  486.      * First, the <code>checkAccess</code> method of this thread is called 
  487.      * with no arguments. This may result in throwing a 
  488.      * <code>SecurityException</code> (in the current thread). 
  489.      * <p>
  490.      * The thread represented by this thread is forced to stop whatever 
  491.      * it is doing abnormally and to throw a newly created 
  492.      * <code>ThreadDeath</code> object as an exception. 
  493.      * <p>
  494.      * It is permitted to stop a thread that has not yet been started. 
  495.      * If the thread is eventually started, it immediately terminates. 
  496.      * <p>
  497.      * An application should not normally try to catch 
  498.      * <code>ThreadDeath</code> unless it must do some extraordinary 
  499.      * cleanup operation (note that the throwing of 
  500.      * <code>ThreadDeath</code> causes <code>finally</code> clauses of 
  501.      * <code>try</code> statements to be executed before the thread 
  502.      * officially dies).  If a <code>catch</code> clause catches a 
  503.      * <code>ThreadDeath</code> object, it is important to rethrow the 
  504.      * object so that the thread actually dies. 
  505.      * <p>
  506.      * The top-level error handler that reacts to otherwise uncaught 
  507.      * exceptions does not print out a message or otherwise notify the 
  508.      * application if the uncaught exception is an instance of 
  509.      * <code>ThreadDeath</code>. 
  510.      *
  511.      * @exception  SecurityException  if the current thread cannot modify
  512.      *               this thread.
  513.      * @see        java.lang.Thread#checkAccess()
  514.      * @see        java.lang.Thread#run()
  515.      * @see        java.lang.Thread#start()
  516.      * @see        java.lang.ThreadDeath
  517.      * @see        java.lang.ThreadGroup#uncaughtException(java.lang.Thread, java.lang.Throwable)
  518.      * @since      JDK1.0
  519.      */
  520.     public final void stop() {
  521.     synchronized (this) {
  522.         checkAccess();
  523.         resume();    // Wake up thread if it was suspended; no-op otherwise
  524.         stop0(new ThreadDeath());
  525.     }
  526.     }
  527.  
  528.     /**
  529.      * Forces the thread to stop executing. 
  530.      * <p>
  531.      * First, the <code>checkAccess</code> method of this thread is called 
  532.      * with no arguments. This may result in throwing a 
  533.      * <code>SecurityException </code>(in the current thread). 
  534.      * <p>
  535.      * If the argument <code>obj</code> is null, a 
  536.      * <code>NullPointerException</code> is thrown (in the current thread). 
  537.      * <p>
  538.      * The thread represented by this thread is forced to complete 
  539.      * whatever it is doing abnormally and to throw the 
  540.      * <code>Throwable</code> object <code>obj</code> as an exception. This 
  541.      * is an unusual action to take; normally, the <code>stop</code> method 
  542.      * that takes no arguments should be used. 
  543.      * <p>
  544.      * It is permitted to stop a thread that has not yet been started. 
  545.      * If the thread is eventually started, it immediately terminates. 
  546.      *
  547.      * @param      obj   the Throwable object to be thrown.
  548.      * @exception  SecurityException  if the current thread cannot modify
  549.      *               this thread.
  550.      * @see        java.lang.Thread#checkAccess()
  551.      * @see        java.lang.Thread#run()
  552.      * @see        java.lang.Thread#start()
  553.      * @see        java.lang.Thread#stop()
  554.      * @since      JDK1.0
  555.      */
  556.     public final synchronized void stop(Throwable o) {
  557.     checkAccess();
  558.     resume();    // Wake up thread if it was suspended; no-op otherwise
  559.     stop0(o);
  560.     }
  561.  
  562.     /**
  563.      * Interrupts this thread.
  564.      *
  565.      * @since   JDK1.0
  566.      */
  567.     // Note that this method is not synchronized.  Three reasons for this:
  568.     // 1) It changes the API.
  569.     // 2) It's another place where the system could hang.
  570.     // 3) All we're doing is turning on a one-way bit.  It doesn't matter
  571.     //    exactly when it's done WRT probes via the interrupted() method.
  572.     public void interrupt() {
  573.     checkAccess();
  574.     interrupt0();
  575.     }
  576.  
  577.     /**
  578.      * Tests if the current thread has been interrupted.
  579.      * Note that <code>interrupted</code> is a static method, while 
  580.      * <code>isInterrupted</code> is called on the current 
  581.      * <code>Thread</code> instance. 
  582.      *
  583.      * @return  <code>true</code> if the current thread has been interrupted;
  584.      *          <code>false</code> otherwise.
  585.      * @see     java.lang.Thread#isInterrupted()
  586.      * @since   JDK1.0
  587.      */
  588.     public static boolean interrupted() {
  589.     return currentThread().isInterrupted(true);
  590.     }
  591.  
  592.     /**
  593.      * Tests if the current thread has been interrupted.
  594.      * Note that <code>isInterrupted</code> 
  595.      * is called on the current <code>Thread</code> instance; by 
  596.      * contrast, <code>interrupted</code> is a static method. 
  597.      *
  598.      * @return  <code>true</code> if this thread has been interrupted;
  599.      *          <code>false</code> otherwise.
  600.      * @see     java.lang.Thread#interrupted()
  601.      * @since   JDK1.0
  602.      */
  603.     public boolean isInterrupted() {
  604.     return isInterrupted(false);
  605.     }
  606.  
  607.     /**
  608.      * Ask if some Thread has been interrupted.  The interrupted state
  609.      * is reset or not based on the value of ClearInterrupted that is
  610.      * passed.
  611.      */
  612.     private native boolean isInterrupted(boolean ClearInterrupted);
  613.  
  614.     /**
  615.      * Destroys this thread, without any cleanup. Any monitors it has 
  616.      * locked remain locked. (This method is not implemented in 
  617.      * Java 1.0.2.)
  618.      *
  619.      * @since   JDK1.0
  620.      */
  621.     public void destroy() {
  622.     throw new NoSuchMethodError();
  623.     }
  624.  
  625.     /**
  626.      * Tests if this thread is alive. A thread is alive if it has 
  627.      * been started and has not yet died. 
  628.      *
  629.      * @return  <code>true</code> if this thread is alive;
  630.      *          <code>false</code> otherwise.
  631.      * @since   JDK1.0
  632.      */
  633.     public final native boolean isAlive();
  634.  
  635.     /**
  636.      * Suspends this thread. 
  637.      * <p>
  638.      * First, the <code>checkAccess</code> method of this thread is called 
  639.      * with no arguments. This may result in throwing a 
  640.      * <code>SecurityException </code>(in the current thread). 
  641.      * <p>
  642.      * If the thread is alive, it is suspended and makes no further 
  643.      * progress unless and until it is resumed. 
  644.      *
  645.      * @exception  SecurityException  if the current thread cannot modify
  646.      *               this thread.
  647.      * @see        java.lang.Thread#checkAccess()
  648.      * @see        java.lang.Thread#isAlive()
  649.      * @since      JDK1.0
  650.      */
  651.     public final void suspend() {
  652.     checkAccess();
  653.     suspend0();
  654.     }
  655.  
  656.     /**
  657.      * Resumes a suspended thread. 
  658.      * <p>
  659.      * First, the <code>checkAccess</code> method of this thread is called 
  660.      * with no arguments. This may result in throwing a 
  661.      * <code>SecurityException</code>(in the current thread). 
  662.      * <p>
  663.      * If the thread is alive but suspended, it is resumed and is 
  664.      * permitted to make progress in its execution. 
  665.      *
  666.      * @exception  SecurityException  if the current thread cannot modify this
  667.      *               thread.
  668.      * @see        java.lang.Thread#checkAccess()
  669.      * @see        java.lang.Thread#isAlive()
  670.      * @since      JDK1.0
  671.      */
  672.     public final void resume() {
  673.     checkAccess();
  674.     resume0();
  675.     }
  676.  
  677.     /**
  678.      * Changes the priority of this thread. 
  679.      * <p>
  680.      * First the <code>checkAccess</code> method of this thread is called 
  681.      * with no arguments. This may result in throwing a 
  682.      * <code>SecurityException</code>. 
  683.      * <p>
  684.      * Otherwise, the priority of this thread is set to the smaller of 
  685.      * the specified <code>newPriority</code> and the maximum permitted 
  686.      * priority of the thread's thread group. 
  687.      *
  688.      * @exception  IllegalArgumentException  If the priority is not in the
  689.      *               range <code>MIN_PRIORITY</code> to
  690.      *               <code>MAX_PRIORITY</code>.
  691.      * @exception  SecurityException  if the current thread cannot modify
  692.      *               this thread.
  693.      * @see        java.lang.Thread#checkAccess()
  694.      * @see        java.lang.Thread#getPriority()
  695.      * @see        java.lang.Thread#getThreadGroup()
  696.      * @see        java.lang.Thread#MAX_PRIORITY
  697.      * @see        java.lang.Thread#MIN_PRIORITY
  698.      * @see        java.lang.ThreadGroup#getMaxPriority()
  699.      * @since      JDK1.0
  700.      */
  701.     public final void setPriority(int newPriority) {
  702.     checkAccess();
  703.     if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
  704.         throw new IllegalArgumentException();
  705.     }
  706.     if (newPriority > group.getMaxPriority()) {
  707.         newPriority = group.getMaxPriority();
  708.     }
  709.     setPriority0(priority = newPriority);
  710.     }
  711.  
  712.     /**
  713.      * Returns this thread's priority.
  714.      *
  715.      * @return  this thread's name.
  716.      * @see     java.lang.Thread#setPriority(int)
  717.      * @since   JDK1.0
  718.      */
  719.     public final int getPriority() {
  720.     return priority;
  721.     }
  722.  
  723.     /**
  724.      * Changes the name of this thread to be equal to the argument 
  725.      * <code>name</code>. 
  726.      * <p>
  727.      * First the <code>checkAccess</code> method of this thread is called 
  728.      * with no arguments. This may result in throwing a 
  729.      * <code>SecurityException</code>. 
  730.      *
  731.      * @param      name   the new name for this thread.
  732.      * @exception  SecurityException  if the current thread cannot modify this
  733.      *               thread.
  734.      * @see        java.lang.Thread#checkAccess()
  735.      * @see        java.lang.Thread#getName()
  736.      * @since      JDK1.0
  737.      */
  738.     public final void setName(String name) {
  739.     checkAccess();
  740.     this.name = name.toCharArray();
  741.     }
  742.  
  743.     /**
  744.      * Returns this thread's name.
  745.      *
  746.      * @return  this thread's name.
  747.      * @see     java.lang.Thread#setName(java.lang.String)
  748.      * @since   JDK1.0
  749.      */
  750.     public final String getName() {
  751.     return String.valueOf(name);
  752.     }
  753.  
  754.     /**
  755.      * Returns this thread's thread group.
  756.      *
  757.      * @return  this thread's thread group.
  758.      * @since   JDK1.0
  759.      */
  760.     public final ThreadGroup getThreadGroup() {
  761.     return group;
  762.     }
  763.  
  764.     /**
  765.      * Returns the current number of active threads in this thread group.
  766.      *
  767.      * @return  the current number of threads in this thread's thread group.
  768.      * @since   JDK1.0
  769.      */
  770.     public static int activeCount() {
  771.     return currentThread().getThreadGroup().activeCount();
  772.     }
  773.  
  774.     /**
  775.      * Copies into the specified array every active thread in this 
  776.      * thread group and its subgroups. This method simply calls the 
  777.      * <code>enumerate</code> method of this thread's thread group with 
  778.      * the array argument. 
  779.      *
  780.      * @return  the number of threads put into the array.
  781.      * @see     java.lang.ThreadGroup#enumerate(java.lang.Thread[])
  782.      * @since   JDK1.0
  783.      */
  784.     public static int enumerate(Thread tarray[]) {
  785.     return currentThread().getThreadGroup().enumerate(tarray);
  786.     }
  787.  
  788.     /**
  789.      * Counts the number of stack frames in this thread. The thread must 
  790.      * be suspended. 
  791.      *
  792.      * @return     the number of stack frames in this thread.
  793.      * @exception  IllegalThreadStateException  if this thread is not suspended.
  794.      * @since      JDK1.0
  795.      */
  796.     public native int countStackFrames();
  797.  
  798.     /**
  799.      * Waits at most <code>millis</code> milliseconds for this thread to 
  800.      * die. A timeout of <code>0</code> means to wait forever. 
  801.      *
  802.      * @param      millis   the time to wait in milliseconds.
  803.      * @exception  InterruptedException  if another thread has interrupted the
  804.      *               current thread.
  805.      * @since      JDK1.0
  806.      */
  807.     public final synchronized void join(long millis) throws InterruptedException {
  808.     long base = System.currentTimeMillis();
  809.     long now = 0;
  810.  
  811.     if (millis < 0) {
  812.             throw new IllegalArgumentException("timeout value is negative");
  813.     }
  814.  
  815.     if (millis == 0) {
  816.         while (isAlive()) {
  817.         wait(0);
  818.         }
  819.     } else {
  820.         while (isAlive()) {
  821.         long delay = millis - now;
  822.         if (delay <= 0) {
  823.             break;
  824.         }
  825.         wait(delay);
  826.         now = System.currentTimeMillis() - base;
  827.         }
  828.     }
  829.     }
  830.  
  831.     /**
  832.      * Waits at most <code>millis</code> milliseconds plus 
  833.      * <code>nanos</code> nanoseconds for this thread to die. 
  834.      *
  835.      * @param      millis   the time to wait in milliseconds.
  836.      * @param      nanos    0-999999 additional nanoseconds to wait.
  837.      * @exception  IllegalArgumentException  if the value of millis is negative
  838.      *               the value of nanos is not in the range 0-999999.
  839.      * @exception  InterruptedException  if another thread has interrupted the
  840.      *               current thread.
  841.      * @since      JDK1.0
  842.      */
  843.     public final synchronized void join(long millis, int nanos) throws InterruptedException {
  844.  
  845.     if (millis < 0) {
  846.             throw new IllegalArgumentException("timeout value is negative");
  847.     }
  848.  
  849.     if (nanos < 0 || nanos > 999999) {
  850.             throw new IllegalArgumentException(
  851.                 "nanosecond timeout value out of range");
  852.     }
  853.  
  854.     if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
  855.         millis++;
  856.     }
  857.  
  858.     join(millis);
  859.     }
  860.  
  861.     /**
  862.      * Waits for this thread to die. 
  863.      *
  864.      * @exception  InterruptedException  if another thread has interrupted the
  865.      *               current thread.
  866.      * @since      JDK1.0
  867.      */
  868.     public final void join() throws InterruptedException {
  869.     join(0);
  870.     }
  871.  
  872.     /**
  873.      * Prints a stack trace of the current thread. This method is used 
  874.      * only for debugging. 
  875.      *
  876.      * @see     java.lang.Throwable#printStackTrace()
  877.      * @since   JDK1.0
  878.      */
  879.     public static void dumpStack() {
  880.     new Exception("Stack trace").printStackTrace();
  881.     }
  882.  
  883.     /**
  884.      * Marks this thread as either a daemon thread or a user thread. The 
  885.      * Java Virtual Machine exits when the only threads running are all 
  886.      * daemon threads. 
  887.      * <p>
  888.      * This method must be called before the thread is started. 
  889.      *
  890.      * @param      on   if <code>true</code>, marks this thread as a
  891.      *                  daemon thread.
  892.      * @exception  IllegalThreadStateException  if this thread is active.
  893.      * @see        java.lang.Thread#isDaemon()
  894.      * @since      JDK1.0
  895.      */
  896.     public final void setDaemon(boolean on) {
  897.     checkAccess();
  898.     if (isAlive()) {
  899.         throw new IllegalThreadStateException();
  900.     }
  901.     daemon = on;
  902.     }
  903.  
  904.     /**
  905.      * Tests if this thread is a daemon thread.
  906.      *
  907.      * @return  <code>true</code> if this thread is a daemon thread;
  908.      *          <code>false</code> otherwise.
  909.      * @see     java.lang.Thread#setDaemon(boolean)
  910.      * @since   JDK1.0
  911.      */
  912.     public final boolean isDaemon() {
  913.     return daemon;
  914.     }
  915.  
  916.     /**
  917.      * Determines if the currently running thread has permission to 
  918.      * modify this thread. 
  919.      * <p>
  920.      * If there is a security manager, its <code>checkAccess</code> method 
  921.      * is called with this thread as its argument. This may result in 
  922.      * throwing a <code>SecurityException</code>. 
  923.      *
  924.      * @exception  SecurityException  if the current thread is not allowed to
  925.      *               access this thread.
  926.      * @see        java.lang.SecurityManager#checkAccess(java.lang.Thread)
  927.      * @since      JDK1.0
  928.      */
  929.     public void checkAccess() {
  930.     SecurityManager security = System.getSecurityManager();
  931.     if (security != null) {
  932.         security.checkAccess(this);
  933.     }
  934.     }
  935.  
  936.     /**
  937.      * Returns a string representation of this thread, including the 
  938.      * thread's name, priority, and thread group.
  939.      *
  940.      * @return  a string representation of this thread.
  941.      * @since   JDK1.0
  942.      */
  943.     public String toString() {
  944.     if (getThreadGroup() != null) {
  945.         return "Thread[" + getName() + "," + getPriority() + "," + 
  946.                     getThreadGroup().getName() + "]";
  947.     } else {
  948.         return "Thread[" + getName() + "," + getPriority() + "," + 
  949.                     "" + "]";
  950.     }
  951.     }
  952.  
  953.     /* Some private helper methods */
  954.     private native void setPriority0(int newPriority);
  955.     private native void stop0(Object o);
  956.     private native void suspend0();
  957.     private native void resume0();
  958.     private native void interrupt0();
  959. }
  960.